@file:Suppress("DEPRECATION")

package com.even.camerarecoder

import android.app.Application
import android.content.Context
import android.graphics.ImageFormat
import android.hardware.Camera
import android.os.Bundle
import android.view.SurfaceHolder
import android.view.SurfaceView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.even.camerarecoder.databinding.ActivityMainBinding
import com.evendai.loglibrary.Timber
import org.doubango.jni.Libyuv

const val TAG = "SurfaceView"

class MainActivity : AppCompatActivity(), Camera.PreviewCallback {

    private lateinit var binding: ActivityMainBinding
    private var camera: Camera? = null
    private var startTime = 0L
    private var receiveFrameCount = 0
    private var isReleasing = false
    private var mH264EncoderThread: H264EncoderThread? = null
    private lateinit var newYuvBytes: ByteArray
    private var audioRecordThread: AudioRecordThread? = null
    private val videoWidth = 640
    private val videoHeight = 480

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        binding.root.setOnLongClickListener {
            val items = arrayOf("修改摄像头预览方向", "打开摄像头", "关闭摄像头")
            AlertDialog
                    .Builder(this)
                    .setItems(items) { _, which ->
                        when (which) {
                            0 -> showSetDisplayOrientationDialog()
                            1 -> openCamera()
                            2 -> closeCamera()
                        }
                    }
                    .create()
                    .show()
            return@setOnLongClickListener true
        }
        setContentView(binding.root)

        PermissionsHelper.requestRecordAudioPermission(this) {
            openCamera()
        }
//        binding.btnStopRecord.setOnClickListener { audioRecordThread.close() }
    }

    private fun showSetDisplayOrientationDialog() {
        val items = arrayOf("0度预览", "90度预览", "180度预览", "270度预览")
        val info = Camera.CameraInfo()
        Camera.getCameraInfo(1, info)
        Timber.i("cameraId为1的摄像头预览方向为：${info.orientation}")
        AlertDialog
                .Builder(this)
                .setSingleChoiceItems(items, -1) { dialog, which ->
                    val degree = which * 90
                    camera?.setDisplayOrientation(degree)
                    dialog.cancel()
                }
                .create()
                .show()
    }

    private fun openCamera() {
        releaseCamera()
        audioRecordThread = AudioRecordThread()
        audioRecordThread?.start()
        PermissionsHelper.requestCameraPermission(this, ::cameraPermissionGranted)
    }

    private fun closeCamera() {
        releaseCamera()
    }

    private fun cameraPermissionGranted() {
        Timber.i("摄像头权限已授权，恭喜哈^_^, thread = ${Thread.currentThread().name}")
        CameraHelper.printCameraInfo(this)
        val surfaceView = MySurfaceView(this).apply { tag = TAG }
        newYuvBytes = ByteArray(videoWidth * videoHeight * 3 / 2)
        surfaceView.holder.setFixedSize(videoWidth, videoHeight)
        surfaceView.holder.addCallback(object : SurfaceHolder.Callback {
            override fun surfaceCreated(holder: SurfaceHolder) {
                Timber.i("surfaceCreated")
                camera = CameraHelper.openFacingBackCamera()?.apply {
                    parameters = parameters.apply {
                        focusMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO
                        previewFormat = ImageFormat.YV12
                        setPreviewSize(videoWidth, videoHeight)
//                        setPictureSize(videoWidth, videoHeight)
                        previewFrameRate = 25
                        //设置镜像效果，支持的值为flip-mode-values=off,flip-v,flip-h,flip-vh;
                        //set("preview-flip", "flip-h")
                    }
                    setPreviewCallback(this@MainActivity)
                    setDisplayOrientation(90)
                    setPreviewDisplay(holder)
                    startPreview()
                    mH264EncoderThread = H264EncoderThread(NgnProxyVideoProducer(videoWidth, videoHeight), false)
                    mH264EncoderThread?.start()
                }
            }

            override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
                Timber.i("surfaceChanged")
            }

            override fun surfaceDestroyed(holder: SurfaceHolder) {
                Timber.i("surfaceDestroyed")
                releaseCamera()
            }
        })
        binding.root.findViewWithTag<SurfaceView>(TAG)?.let { binding.root.removeView(it) }
        binding.root.addView(surfaceView)
    }

    class MySurfaceView(context: Context) : SurfaceView(context) {

    }

    override fun onPreviewFrame(data: ByteArray, camera: Camera) {
        if (startTime == 0L) startTime = System.currentTimeMillis()
        receiveFrameCount++
        if (System.currentTimeMillis() - startTime >= 10000) {
            Timber.i("摄像头每10秒传出${receiveFrameCount}帧")
            startTime = System.currentTimeMillis()
            receiveFrameCount = 0
        }
        Libyuv.YV12ToNV12Rotate270Or90(data, newYuvBytes, videoWidth, videoHeight, false)
        mH264EncoderThread?.addYUVDatas(newYuvBytes)
        newYuvBytes = data
    }

    private fun releaseCamera() {
        if (!isReleasing) {
            isReleasing = true
            camera?.setPreviewCallback(null)
            camera?.stopPreview()
            camera?.release()
            camera = null
            mH264EncoderThread?.close()
            mH264EncoderThread = null
            isReleasing = false
            audioRecordThread?.close()
            audioRecordThread = null
        }
    }

}